<template>
  <div class="media-upload">
    <!-- 上传组件 -->
    <n-upload
      ref="uploadRef"
      :file-list="fileList"
      @update:file-list="handleFileListChange"
      list-type="image-card"
      :max="maxFiles"
      :custom-request="customUpload"
      :accept="acceptTypes"
      @change="handleChange"
      @preview="handlePreview"
    >
      <div class="upload-trigger">
        <n-icon size="48" :depth="3">
          <AddIcon />
        </n-icon>
        <n-text style="font-size: 12px; margin-top: 8px">
          {{ uploadText }}
        </n-text>
      </div>
    </n-upload>

    <!-- 图片预览模态框 -->
    <n-modal
      :show="previewVisible"
      @update:show="previewVisible = $event"
      preset="card"
      style="width: 90vw; max-width: 800px"
      :mask-closable="true"
    >
      <div class="preview-content">
        <!-- 图片预览 -->
        <n-image
          v-if="previewType === 'image' && previewUrl"
          :src="previewUrl"
          :alt="previewFileName"
          object-fit="contain"
          style="max-height: 70vh; width: 100%"
        />

        <!-- 视频预览 -->
        <video
          v-else-if="previewType === 'video' && previewUrl"
          :src="previewUrl"
          controls
          style="max-height: 70vh; width: 100%"
        />
      </div>
    </n-modal>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, h } from 'vue'
import { useMessage } from 'naive-ui'
import type { UploadFileInfo } from 'naive-ui'
import { Add as AddIcon } from '@vicons/ionicons5'
import { uploadApi, type UploadResult } from '@/api/upload'
import { smartCompress, type CompressionResult, formatFileSize } from '../../utils/imageCompression'

interface Props {
  modelValue: UploadFileInfo[]
  maxFiles?: number
  accept?: 'image' | 'video' | 'all'
  uploadText?: string
}

const props = withDefaults(defineProps<Props>(), {
  maxFiles: 9,
  accept: 'all',
  uploadText: '点击上传'
})

const emit = defineEmits<{
  'update:modelValue': [files: UploadFileInfo[]]
  change: [files: UploadFileInfo[]]
}>()

const message = useMessage()
const uploadRef = ref()
const fileList = ref<UploadFileInfo[]>(props.modelValue)
const previewVisible = ref(false)
const previewUrl = ref('')
const previewFileName = ref('')
const previewType = ref<'image' | 'video'>('image')
const uploadedFiles = ref<string[]>([])

// 根据accept类型设置接受的文件类型
const acceptTypes = computed(() => {
  switch (props.accept) {
    case 'image':
      return 'image/*'
    case 'video':
      return 'video/*'
    case 'all':
    default:
      return 'image/*,video/*'
  }
})

// 监听 modelValue 变化，同步到内部 fileList
watch(() => props.modelValue, (newValue) => {
  console.log('MediaUpload modelValue 变化:', newValue)
  fileList.value = [...newValue]

  // 更新已上传文件列表
  uploadedFiles.value = newValue
    .filter(file => file.status === 'finished' && file.url)
    .map(file => file.url!)
}, { deep: true, immediate: true })


// 自定义上传处理
const customUpload = async ({ file }: { file: UploadFileInfo }) => {
  console.log('MediaUpload customUpload 开始，file:', file)
  try {
    const fileObj = file.file as File
    let result: UploadResult
    let uploadFile = fileObj

    // 如果是图片文件，先进行压缩
    if (fileObj.type.startsWith('image/')) {
      console.log('开始压缩图片文件:', fileObj.name, fileObj.type, '原始大小:', formatFileSize(fileObj.size))

      try {
        const compressionResult = await smartCompress(fileObj)
        uploadFile = compressionResult.file

        console.log('压缩完成:', {
          原始大小: formatFileSize(compressionResult.originalSize),
          压缩后大小: formatFileSize(compressionResult.compressedSize),
          压缩比例: compressionResult.compressionRatio.toFixed(1) + '%'
        })

        // 如果压缩比例超过30%，显示提示
        if (compressionResult.compressionRatio > 30) {
          message.info(`图片已压缩 ${compressionResult.compressionRatio.toFixed(1)}%，从 ${formatFileSize(compressionResult.originalSize)} 压缩到 ${formatFileSize(compressionResult.compressedSize)}`)
        }

        // 更新文件对象
        file.file = uploadFile
      } catch (compressionError) {
        console.warn('图片压缩失败，使用原文件:', compressionError)
        message.warning('图片压缩失败，将使用原文件上传')
        // 压缩失败时使用原文件
        uploadFile = fileObj
      }

      console.log('上传图片文件:', uploadFile.name, uploadFile.type)
      result = await uploadApi.uploadImage(uploadFile)
    } else if (fileObj.type.startsWith('video/')) {
      console.log('上传视频文件:', fileObj.name, fileObj.type)
      result = await uploadApi.uploadVideo(fileObj)
    } else {
      throw new Error('不支持的文件类型')
    }

    console.log('上传成功，返回的结果:', result)

    // 更新文件状态
    file.url = result.url
    file.status = 'finished' as const

    // 更新文件的类型信息 - 不能直接修改 Blob 的 type 属性
    // 我们将在 file 对象上添加一个自定义的 fileType 属性
    ;(file as any).fileType = result.fileType

    // 确保文件对象有正确的类型信息用于预览
    if (file.file) {
      // 创建一个新的 File 对象，包含正确的类型信息
      const newFile = new File([file.file], file.file.name, {
        type: result.fileType,
        lastModified: file.file.lastModified
      })
      file.file = newFile
    }

    // 记录上传的文件URL
    uploadedFiles.value.push(result.url)

    console.log('更新后的 file:', file)
    console.log('当前 uploadedFiles:', uploadedFiles.value)

    // 找到并更新 fileList 中对应的文件
    const fileIndex = fileList.value.findIndex(f => f.id === file.id)
    if (fileIndex !== -1) {
      fileList.value[fileIndex].url = result.url
      fileList.value[fileIndex].status = 'finished' as const
      ;(fileList.value[fileIndex] as any).fileType = result.fileType

      // 确保 fileList 中的文件对象也有正确的类型信息
      if (fileList.value[fileIndex].file) {
        const newFile = new File([fileList.value[fileIndex].file!], fileList.value[fileIndex].file!.name, {
          type: result.fileType,
          lastModified: fileList.value[fileIndex].file!.lastModified
        })
        fileList.value[fileIndex].file = newFile
      }
    }

    // 手动触发文件列表更新，确保父组件能收到更新
    const updatedFileList = [...fileList.value]
    fileList.value = updatedFileList
    emit('update:modelValue', updatedFileList)

    message.success('上传成功')
  } catch (error) {
    console.error('上传失败:', error)
    file.status = 'error'
    message.error('上传失败')
  }
}

// 处理文件列表变化
const handleFileListChange = (files: UploadFileInfo[]) => {
  console.log('MediaUpload handleFileListChange 被调用，files:', files)
  fileList.value = files

  // 更新已上传文件列表（移除自动删除七牛云文件的逻辑）
  const currentUrls = files
    .filter(file => file.status === 'finished' && file.url)
    .map(file => file.url!)

  console.log('当前文件URL列表:', currentUrls)
  uploadedFiles.value = currentUrls

  console.log('更新后的 uploadedFiles:', uploadedFiles.value)

  // 同步到父组件
  emit('update:modelValue', files)
}

// 移除自动删除七牛云文件的逻辑，避免误删数据

// 处理文件变化
const handleChange = (options: { fileList: UploadFileInfo[] }) => {
  console.log('MediaUpload handleChange 被调用，options:', options)
  emit('change', options.fileList)
}

// 处理预览
const handlePreview = (file: UploadFileInfo) => {
  if (!file.url) return

  previewUrl.value = file.url
  previewFileName.value = file.name || '文件'

  // 改进文件类型检测逻辑
  // 首先检查自定义的 fileType 属性
  if ((file as any).fileType) {
    const fileType = (file as any).fileType
    if (fileType.startsWith('image/')) {
      previewType.value = 'image'
    } else if (fileType.startsWith('video/')) {
      previewType.value = 'video'
    } else {
      previewType.value = 'image' // 默认为图片
    }
  } else if (file.file?.type?.startsWith('image/')) {
    previewType.value = 'image'
  } else if (file.file?.type?.startsWith('video/')) {
    previewType.value = 'video'
  } else {
    // 如果没有文件类型信息，尝试从URL或文件名推断
    const url = file.url.toLowerCase()
    const name = file.name.toLowerCase()
    if (url.includes('.jpg') || url.includes('.jpeg') || url.includes('.png') ||
        url.includes('.gif') || url.includes('.webp') || url.includes('.bmp') ||
        name.includes('.jpg') || name.includes('.jpeg') || name.includes('.png') ||
        name.includes('.gif') || name.includes('.webp') || name.includes('.bmp')) {
      previewType.value = 'image'
    } else if (url.includes('.mp4') || url.includes('.avi') || url.includes('.mov') ||
               url.includes('.wmv') || url.includes('.flv') || url.includes('.webm') ||
               name.includes('.mp4') || name.includes('.avi') || name.includes('.mov') ||
               name.includes('.wmv') || name.includes('.flv') || name.includes('.webm')) {
      previewType.value = 'video'
    } else {
      // 默认为图片
      previewType.value = 'image'
    }
  }

  previewVisible.value = true
}

// 添加一个辅助函数来检测文件类型
const getFileType = (file: UploadFileInfo): string => {
  // 首先检查自定义的 fileType 属性
  if ((file as any).fileType) {
    return (file as any).fileType
  }

  // 然后检查 file 对象的 type
  if (file.file?.type) {
    return file.file.type
  }

  // 最后从URL推断
  const url = file.url?.toLowerCase() || ''
  if (url.includes('.jpg') || url.includes('.jpeg')) {
    return 'image/jpeg'
  } else if (url.includes('.png')) {
    return 'image/png'
  } else if (url.includes('.gif')) {
    return 'image/gif'
  } else if (url.includes('.webp')) {
    return 'image/webp'
  } else if (url.includes('.bmp')) {
    return 'image/bmp'
  } else if (url.includes('.mp4')) {
    return 'video/mp4'
  } else if (url.includes('.avi')) {
    return 'video/avi'
  } else if (url.includes('.mov')) {
    return 'video/quicktime'
  } else if (url.includes('.wmv')) {
    return 'video/x-ms-wmv'
  } else if (url.includes('.flv')) {
    return 'video/x-flv'
  } else if (url.includes('.webm')) {
    return 'video/webm'
  }

  return 'image/jpeg' // 默认
}

// 暴露方法给父组件
defineExpose({
  previewFile: handlePreview
})
</script>

<style scoped>
.media-upload {
  width: 100%;
}

.upload-trigger {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  padding: 20px;
}

.preview-content {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 200px;
}
</style>
